package edu.bu.cs673.superkids123.children.view.games;

import javax.swing.ImageIcon;
import javax.swing.JLabel;

import edu.bu.cs673.superkids123.children.model.resources.ChildrenResource;
import edu.bu.cs673.superkids123.children.model.resources.ChildrenResourceProvider;

/**
 * A class that extends ImageIcon which will represent the crosshair in the Archery Game.
 * 
 * @author Noah Fredriks
 */
public class ArcheryGameCrosshair extends JLabel implements Runnable {

	/**
	 * The default UID
	 */
	private static final long serialVersionUID = 1L;

	/**
	 * The ImageIcon of used to display the picture in the label;
	 * 
	 */
	private static ImageIcon icon;

	/**
	 * The height at which the crosshair lies
	 */
	private static final int VERT_DIST_DOWN = 220;

	/**
	 * The number of pixels the crosshair jumps at a time in order to speed up the movement and
	 * lessen processor intensity
	 */
	private static final int MOVE_CONST = 3;

	/**
	 * The default width of the game window
	 */
	private static final int WINDOW_WIDTH = 720;

	/**
	 * x dimension of the crosshair icon
	 */
	private static int ICON_WIDTH;

	/**
	 * y dimension of the crosshair icon
	 */
	private static int ICON_HEIGHT;

	/**
	 * The flag which signifies if the crosshair is moving.
	 */
	private boolean moving;

	/**
	 * The speed at which the crosshair moves from 1 - 10
	 */
	private int difficulty;

	/**
	 * The position of the origin of the crosshair label
	 */
	private int position;

	/**
	 * A flag which signifies if the crosshair should move to the right or not
	 */
	private boolean rightWard;

	/**
	 * Creates a ArcheryGameCrosshair ImageIcon from a prespecified image filename
	 */
	public ArcheryGameCrosshair() {
		super();

		ChildrenResourceProvider provider = ChildrenResourceProvider.getInstance();
		icon = provider.getImage(ChildrenResource.imageCrosshair);
		setIcon(icon);
		ICON_WIDTH = icon.getIconWidth();
		ICON_HEIGHT = icon.getIconHeight();

		// Default difficulty
		difficulty = 5;

		// Start the crosshair at the left of the screen moving right
		moving = true;
		position = 0;
		rightWard = true;
		setBounds();
	}

	/**
	 * Makes the crosshair move back and forth until the moving flag is false
	 */
	private void move() {

		// Loop to move the crosshair back and forth
		while (moving) {

			rightWard = isRightWard(rightWard);

			// Move right
			while (moving && rightWard) {

				setBounds();
				position += MOVE_CONST;

				try {
					Thread.sleep(10 - difficulty);

				} catch (InterruptedException iE) {
					System.err.println("ArcheryGameCrosshair: " + iE.getMessage());
				}

				rightWard = isRightWard(rightWard);
			}

			// Move left
			while (moving && !rightWard) {

				setBounds();
				position -= MOVE_CONST;

				try {
					Thread.sleep(10 - difficulty);

				} catch (InterruptedException iE) {
					System.err.println("ArcheryGameCrosshair: " + iE.getMessage());
				}

				rightWard = isRightWard(rightWard);
			}

		}

	}

	/**
	 * Determines the direction the crosshair should go
	 * 
	 * @param rightWard
	 *            the direction previously set
	 * @return the new direction
	 */
	private boolean isRightWard(boolean rightWard) {
		boolean retVal = rightWard;

		if (position < 0 + MOVE_CONST) {
			retVal = true;
		} else if ((WINDOW_WIDTH - ICON_WIDTH - MOVE_CONST) < position) {
			retVal = false;
		}

		return retVal;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see java.lang.Runnable#run()
	 */
	public void run() {
		moving = true;
		move();
	}

	/**
	 * Overrides default setBounds to include the values which will be used for this class
	 */
	public void setBounds() {
		setBounds(position, VERT_DIST_DOWN, ICON_WIDTH, ICON_HEIGHT);
	}

	/**
	 * Stops the movement of the crosshair, ending the thread's activity.
	 */
	public void stop() {
		moving = false;
	}

	/**
	 * Return the status of the crosshair
	 * 
	 * @return if the crosshair should be moving
	 */
	public boolean isMoving() {
		return moving;
	}

	/**
	 * Sets the speed of movement of the crosshair
	 * 
	 * @param diff
	 *            desired crosshair speed to be set
	 */
	public void setDifficulty(int diff) {
		difficulty = diff;
	}

	/**
	 * Returns the movement speed of the crosshair
	 * 
	 * @return difficulty int value of crosshair speed
	 */
	public int getDifficulty() {
		return difficulty;
	}

	public int getX() {
		return position;
	}

}